// File generated from our OpenAPI spec by Stainless.

package com.metest.api.client

import com.metest.api.core.ClientOptions
import com.metest.api.core.getPackageVersion
import com.metest.api.services.blocking.PetService
import com.metest.api.services.blocking.PetServiceImpl
import com.metest.api.services.blocking.RestService
import com.metest.api.services.blocking.RestServiceImpl
import com.metest.api.services.blocking.StoreService
import com.metest.api.services.blocking.StoreServiceImpl
import com.metest.api.services.blocking.UserService
import com.metest.api.services.blocking.UserServiceImpl
import java.util.function.Consumer

class MetestClientImpl(private val clientOptions: ClientOptions) : MetestClient {

    private val clientOptionsWithUserAgent =
        if (clientOptions.headers.names().contains("User-Agent")) clientOptions
        else
            clientOptions
                .toBuilder()
                .putHeader("User-Agent", "${javaClass.simpleName}/Java ${getPackageVersion()}")
                .build()

    // Pass the original clientOptions so that this client sets its own User-Agent.
    private val async: MetestClientAsync by lazy { MetestClientAsyncImpl(clientOptions) }

    private val withRawResponse: MetestClient.WithRawResponse by lazy {
        WithRawResponseImpl(clientOptions)
    }

    private val user: UserService by lazy { UserServiceImpl(clientOptionsWithUserAgent) }

    private val pet: PetService by lazy { PetServiceImpl(clientOptionsWithUserAgent) }

    private val store: StoreService by lazy { StoreServiceImpl(clientOptionsWithUserAgent) }

    private val rest: RestService by lazy { RestServiceImpl(clientOptionsWithUserAgent) }

    override fun async(): MetestClientAsync = async

    override fun withRawResponse(): MetestClient.WithRawResponse = withRawResponse

    override fun withOptions(modifier: Consumer<ClientOptions.Builder>): MetestClient =
        MetestClientImpl(clientOptions.toBuilder().apply(modifier::accept).build())

    override fun user(): UserService = user

    override fun pet(): PetService = pet

    override fun store(): StoreService = store

    override fun rest(): RestService = rest

    override fun close() = clientOptions.close()

    class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) :
        MetestClient.WithRawResponse {

        private val user: UserService.WithRawResponse by lazy {
            UserServiceImpl.WithRawResponseImpl(clientOptions)
        }

        private val pet: PetService.WithRawResponse by lazy {
            PetServiceImpl.WithRawResponseImpl(clientOptions)
        }

        private val store: StoreService.WithRawResponse by lazy {
            StoreServiceImpl.WithRawResponseImpl(clientOptions)
        }

        private val rest: RestService.WithRawResponse by lazy {
            RestServiceImpl.WithRawResponseImpl(clientOptions)
        }

        override fun withOptions(
            modifier: Consumer<ClientOptions.Builder>
        ): MetestClient.WithRawResponse =
            MetestClientImpl.WithRawResponseImpl(
                clientOptions.toBuilder().apply(modifier::accept).build()
            )

        override fun user(): UserService.WithRawResponse = user

        override fun pet(): PetService.WithRawResponse = pet

        override fun store(): StoreService.WithRawResponse = store

        override fun rest(): RestService.WithRawResponse = rest
    }
}
